package com.csit.util;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.*;

/**
 * User: xpk
 * Date: 12-7-18
 * Time: 下午1:54
 */
public class JAXBUtils {
	private static final String DEFAULT_CHARSET = "UTF-8";

	@SuppressWarnings("unchecked")
	public static Object parseXML(Class clz, String xml) throws JAXBException {
		InputStream is;
		try {
			String charset = DEFAULT_CHARSET;
			if (System.getProperty("file.encoding") != null) {
				charset = System.getProperty("file.encoding");
			}
			//try get charset from text
			if (xml.startsWith("<?")) {
				charset = xml.substring(0, xml.indexOf("?>"));
				int pos = xml.toLowerCase().indexOf("encoding=");
				if (pos != -1) {
					charset = charset.substring(pos + 9);//"encoding=".length()
					pos = charset.indexOf(" ");
					if (pos == -1) {
						pos = charset.lastIndexOf(charset.substring(0, 1));
					} else {
						pos -= 1;      //\"GB2312\"
					}
					charset = charset.substring(1, pos);
				}
			}

			is = new ByteArrayInputStream(xml.getBytes(charset));
		} catch (UnsupportedEncodingException e) {
			throw new JAXBException(e.getMessage(), e);
		}
		return parseXML(clz, is);
	}

	@SuppressWarnings("unchecked")
	public static Object parseXML(Class clz, InputStream is) throws JAXBException {
		return getContext(clz).createUnmarshaller().unmarshal(is);

	}

	public static String toXML(Object obj) throws JAXBException {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		toXML(obj, outputStream);
		try {
			return new String(outputStream.toByteArray(), DEFAULT_CHARSET);
		} catch (UnsupportedEncodingException e) {
			throw new JAXBException(e.getMessage(), e);
		}
	}

	@SuppressWarnings("unchecked")
	public static JAXBContext getContext(Class clz) throws JAXBException {
		return JAXBContext.newInstance(clz);
	}

	public static void toXML(Object obj, OutputStream out) throws JAXBException {
		Marshaller marshaller = getContext(obj.getClass()).createMarshaller();
		marshaller.marshal(obj, out);
	}
}
